<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            padding-bottom: 800px;
        }

        table {
            border-collapse: collapse;
            border-spacing: 0;
            cursor: pointer;
        }

        table td {
            border: 1px solid black;
            padding: 4px 8px;
        }

        table thead {
            background-color: #dedede;
        }
    </style>
</head>

<body>
    <!-- 
    vue的知识回顾【vue就是封装了DOM操作的工具】：
        MVVM对开发者影响 : 将数据对DOM操作进行高度的自有封装，开发只需使用简单语法即可实现数据变化DOM更新
        vue的模板语法的本质 : vue高度封装的具有不同功能的DOM操作方法
        vue的指令 : 基于特定功能封装的DOM基础操作
    -->
    <div id="app">
        <input type="color" v-model="color">
        <table>
            <thead>
                <tr>
                    <td>id</td>
                    <td>name</td>
                    <td>username</td>
                    <td>age</td>
                    <td>tel</td>
                </tr>
            </thead>
            <tbody>
                <!-- <tr v-for=" u in users " :key="u.id" v-one> -->
                <!-- <tr v-for=" u in users " :key="u.id" v-one=" 'bl'+'ue' "> -->
                <!-- <tr v-for=" u in users " :key="u.id" v-one=" color "> -->
                <!-- <tr v-for=" u in users " :key="u.id" v-one:background-color=" color "> -->
                <tr v-for=" u in users " :key="u.id" v-one:background-color.both=" color ">
                <!-- <tr v-for=" u in users " :key="u.id" v-two:background-color.both=" color "> -->
                    <td>{{ u.id }}</td>
                    <td>{{ u.name }}</td>
                    <td>{{ u.username }}</td>
                    <td>{{ u.age }}</td>
                    <td>{{ u.tel }}</td>
                </tr>
            </tbody>
        </table>
    </div>
    <script src="../assets/mock/mock-min.js"></script>
    <script type="module">
        // 全局指令:通过应用app定义的全局指令，在应用环境中的任意vue实例容器中都可以直接使用
        // 局部指令：通过directives定义的局部指令，只能被使用于该指令定义时的vue实例的容器中
        import { createApp } from "../assets/vue3/vue.esm-browser.js";
        const app = createApp({
            data() {
                return {
                    color: "#00ff00",
                    users: Mock.mock({
                        "list|1-1": [
                            {
                                id: "@id",
                                name: "@cname",
                                username: "@word",
                                "age|20-80": 23,
                                tel: /^1\d{10}$/
                            }
                        ]
                    }).list
                }
            },
            // 局部指令定义,一个key:value组合为一个自定义指令
            directives: {
                // key 为指令名
                // value 为指令的取值 callback|options
                two: function (el, binding) {
                    // console.log(this) // 自定义指令无论是全局还是局部this都不指向于vue实例对象
                    el.addEventListener("mouseover", function () {
                        el.style[binding.arg || "color"] = binding.value || "red";
                        if (binding.modifiers.both) {
                            el.style.fontWeight = "bold"
                        }
                    })
                    el.addEventListener("mouseout", function () {
                        // el.style.color=null;
                        el.style[binding.arg || "color"] = null;
                        el.style.fontWeight = null;
                    })
                }
            }
        });
        // vue的自定义指令，是在vue语法基础上扩展的允许开发者自行定义DOM操作对应模板语法的特殊接口
        // 全局指令的定义
        // app.directive(directiveName,callback|Options)
        //      + directiveName 自定义vue指令名称 => 指令名可以使用驼峰名称，但页面使用时需要转换为连字符
        //                                       => 例如  指令名 oneDir 页面使用 v-one-dir
        //      + callback|options  【 callback == options.mounted && options.updated】
        //          - callback(el,binding) 自定义指令在模板中进行使用时的回调方法
        //                 * el 绑定该指令的DOM元素【经过vue虚拟DOM渲染的最终DOM】
        //                 * binding 指令在模板中使用式，绑定的各种相关数据，和指令的相关基本配置对象
        //                      -> value 是指令在模板中进行调用时 = 右侧的运算取值结果
        //                      -> oldValue 是指令=右侧的动态取值发生变化时，变化前的旧值
        //                      -> arg 是指令名后以 : 方式定义的参数值
        //                      -> modifiers 是指令在模板中使用时通过 . 增加修饰符存储对象
        //                                   使用的所有修饰符都会以修饰符名称作为key 取值true进行描述
        //          - options 分解自定义指令生命周期钩子函数的定义规则
        //                  在绑定元素的 attribute 前 或事件监听器应用前调用
        //                  created(el, binding, vnode, prevVnode) {},
        //                  // 在元素被插入到 DOM 前调用
        //                  beforeMount(el, binding, vnode, prevVnode) {},
        //                  // 他自己的所有子节点都挂载完成后调用
        //                  mounted(el, binding, vnode, prevVnode) {},
        //                  // 绑定元素的父组件更新前调用
        //                  beforeUpdate(el, binding, vnode, prevVnode) {},
        //                  // 他自己的所有子节点都更新后调用
        //                  updated(el, binding, vnode, prevVnode) {},
        //                  // 绑定元素的父组件卸载前调用
        //                  beforeUnmount(el, binding, vnode, prevVnode) {},
        //                  // 绑定元素的父组件卸载后调用
        //                  unmounted(el, binding, vnode, prevVnode) {}
        //      + vnode
        //      + preVnode

        // 自定义指令在vue的模板环境中，通过 v-自定义指令 完成调用，同时可以完全使用指令完整语法
        app.directive("one", function (el, binding,vnode,preVnode) {
            // console.log("menu自定义指令")
            // console.log(el)
            // console.log(binding)
            console.log(vnode)
            console.log(preVnode)
            el.addEventListener("mouseover", function () {
                // el.style.color= binding.value||"red";
                el.style[binding.arg || "color"] = binding.value || "red";
                if (binding.modifiers.both) {
                    el.style.fontWeight = "bold"
                }
            })
            el.addEventListener("mouseout", function () {
                // el.style.color=null;
                el.style[binding.arg || "color"] = null;
                el.style.fontWeight = null;
            })
        })

        app.mount("#app")
    </script>
</body>

</html>